package cn.tedu.reflection;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

//测试 暴力反射
//总结
//1.API方法改变--c.getFields/method改为getDeclaredFields/methods
//2.执行private/default方法时需要开启权限--f.setAccessible(true);
//优点：比普通方法的反射，可以获取到更多的资源，不止public的,甚至default、private都可以
public class Test3 {
    public static void main(String[] args) throws Exception {
//        method();//所有方法
        method2();//所有属性
    }
    //所有属性
    private static void method2() throws Exception {
        Class c=Human.class;
//        c.getFields();//只能获取public的
        Field[] a=c.getDeclaredFields();
        for (Field f :a) {
               Object obj=c.newInstance();
            // 对public的属性get/set
            if (f.getName().equals("name")){
                f.setAccessible(true);//开启权限，public修饰符中可以省略不写
               f.set(obj,"java");
                System.out.println(f.get(obj));
            }
            //对private的属性get/set
            if (f.getName().equals("age")){
                f.setAccessible(true);//开启权限
                f.set(obj,20000);
                System.out.println(f.get(obj));
            }
        }
    }

    //所有方法
    public static void method() throws Exception {
        //1.创建Class对象
        Class c=Human.class;
        //2.获取反射的方法
//        Method [] a=c.getMethods();//只能获取public的方法
        Method [] a=c.getDeclaredMethods();//能获取public/default/private的方法
        for (Method m : a) {
           //只执行test1
            Object obj=c.newInstance();
            if(m.getName().equals("test1")){
                m.setAccessible(true);//公开的也可以设置权限，不设置也可以。
                m.invoke(obj);
            }
            //想执行private/default的
            if(m.getName().equals("test2")){
                //开启权限，否则操作私有资源会抛异常IllegalAccessException
                m.setAccessible(true);
                m.invoke(obj,"hello java");
            }
        }
    }
}
